﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Reflection;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
/****************************************
 * 标题：IOC注入助手类
 * 描述：
 * 开发：单车上的程序猿（2014年11月1日 12:25:27）
 * 编辑：
 * 备注：
 * *************************************/

namespace QiBu.Api.Helper.Com
{
    /// <summary>
    /// IOC操作类
    /// </summary>
    public sealed class UnityIOC : IServiceProvider
    {
        private IUnityContainer container;
        private UnityIOC()
        {

            UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
            container = new UnityContainer();
            section.Configure(container);
        }

        public static UnityIOC Instance
        {
            get { return new UnityIOC(); }
        }


        private IEnumerable<ParameterOverride> GetParameterOverrides(object overridedArguments)
        {
            List<ParameterOverride> overrides = new List<ParameterOverride>();
            Type argumentsType = overridedArguments.GetType();
            argumentsType.GetProperties(BindingFlags.Public | BindingFlags.Instance)
                .ToList()
                .ForEach(property =>
                {
                    var propertyValue = property.GetValue(overridedArguments, null);
                    var propertyName = property.Name;
                    overrides.Add(new ParameterOverride(propertyName, propertyValue));
                });
            return overrides;
        }

        public T GetService<T>()
        {
            try
            {
                return container.Resolve<T>();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public T GetService<T>(object overridedArguments)
        {
            var overrides = GetParameterOverrides(overridedArguments);
            return container.Resolve<T>(overrides.ToArray());
        }

        public object GetService(Type serviceType, object overridedArguments)
        {
            var overrides = GetParameterOverrides(overridedArguments);
            return container.Resolve(serviceType, overrides.ToArray());
        }

        public object GetService(Type serviceType)
        {
            return container.Resolve(serviceType);
        }

    }
}
